package cn.itcast.bos.realm;

import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.itcast.bos.domain.system.Permission;
import cn.itcast.bos.domain.system.Role;
import cn.itcast.bos.domain.system.User;
import cn.itcast.bos.service.system.PermissionService;
import cn.itcast.bos.service.system.RoleService;
import cn.itcast.bos.service.system.UserService;

//@Service("bosRealm")
public class BosRealm extends AuthorizingRealm {

	@Autowired
	private UserService userService;
	
	@Autowired
	private RoleService roleService;
	
	@Autowired
	private PermissionService permissionService;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
		System.err.println("Shiro 授权......");
		//进行授权
		SimpleAuthorizationInfo simpleAuthenticationInfo = new SimpleAuthorizationInfo();
		//根据当前登录用户查询对应角色和权限
		Subject subject = SecurityUtils.getSubject();
		User user = (User) subject.getPrincipal();
		//调用service查询用户
		List<Role> roles = roleService.findByUser(user);
		for (Role role : roles) {
			simpleAuthenticationInfo.addRole(role.getKeyword());
		}
		//调用service, 查看权限
		List<Permission> permissions = permissionService.findByUser(user);
		for (Permission permission : permissions) {
			simpleAuthenticationInfo.addStringPermission(permission.getKeyword());
		}
		return simpleAuthenticationInfo;
	}

	//认证就是判断用户名密码是否正确, 如果正确,就登陆,不正确就不让登录,输入的用户密码会保存在subject中,
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		System.err.println("shiro 认证......");
		// 转换token
		UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
		// 根据用户名查询用户信息
		User user = userService.findByUsername(usernamePasswordToken.getUsername());
//			
		if (user == null) {
			// 说明用户不存在
			return null;
		} else {
			// 用户存在
			// 当返回用户密码时,securityManager安全管理器,自动比较返回密码和用户输入的密码
			// 如果密码一致,登陆成功,不一致报异常
			return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
		}
	}

}
